package cn.ydw.community.controller;


import cn.ydw.community.annotation.LoginRequired;
import cn.ydw.community.entity.User;
import cn.ydw.community.service.LikeService;
import cn.ydw.community.service.UserService;
import cn.ydw.community.service.impl.FollowService;
import cn.ydw.community.util.CommonUtils;
import cn.ydw.community.util.CommunityConstant;
import cn.ydw.community.util.HostHolder;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author dw
 * @since 2020-10-18
 */
@Controller
@RequestMapping("/user")
@Slf4j
public class UserController implements CommunityConstant {

    @Value("${commons.domain.upload}")
    private String uploadPath;

    @Value("${commons.domain.url}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Autowired
    private UserService userService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private FollowService followService;

    @Value("${qiniu.key.access}")
    private String accessKey;

    @Value("${qiniu.key.secret}")
    private String secretKey;

    @Value("${qiniu.bucket.header.name}")
    private String headerBucketName;

    @Value("${quniu.bucket.header.url}")
    private String headerBucketUrl;

    /**
     * 我们要在上传文件时，附带一些相应的参数，所以在进入页面时保存在model中
     */
    @LoginRequired
    @RequestMapping(path = "/setting", method = RequestMethod.GET)
    public String getSettingPage(Model model) {
        String fileName = CommonUtils.generateUUID();
        // 设置响应信息
        StringMap policy = new StringMap();
        policy.put("returnBody", CommonUtils.getJSON(0));
        // 生成上传凭证
        Auth auth = Auth.create(accessKey, secretKey);
        String uploadToken = auth.uploadToken(headerBucketName, fileName, 3600, policy);
        model.addAttribute("uploadToken", uploadToken);
        model.addAttribute("fileName", fileName);
        return "/site/setting";
    }

    /**
     * 重构更新头像路径
     */
    @PostMapping("/header/url")
    public @ResponseBody String updateHeaderUrl(String fileName){
        if (StringUtils.isBlank(fileName)) {
            return CommonUtils.getJSON(1, "文件名不能为空!");
        }
        String url = headerBucketUrl + "/" + fileName;
        userService.updateHeader(hostHolder.getUser().getId(), url);
        return CommonUtils.getJSON(0);
    }

    /**
     * 上传图片,废弃
     */
    @LoginRequired
    @PostMapping("/upload")
    public String uploadImg(MultipartFile headerImg, Model model){
        if (headerImg == null){
            model.addAttribute("error", "还未选择图片");
            return "/site/setting";
        }
        // 上传的文件名
        String filename = headerImg.getOriginalFilename();
        // 后缀名
        String suffix = filename.substring(filename.lastIndexOf("."));
        if(StringUtils.isBlank(suffix)){
            model.addAttribute("error", "文件格式不正确");
            return "/site/setting";
        }
        //生成随机文件名
        filename = CommonUtils.generateUUID() + suffix;
        // 文件存放路径
        File dist = new File(uploadPath + "/" + filename);
        //存储文件
        try {
            headerImg.transferTo(dist);
        } catch (IOException e) {
            log.error("文件上传失败：" + e.getMessage());
            throw new RuntimeException("文件上传失败，服务器异常！" + e);
        }
        // 更新用户当前头像,先从holder中获取用户信息
        User user = hostHolder.getUser();
        String headerUrl = domain + contextPath + "/user/header/" +filename;
        userService.updateHeader(user.getId(),headerUrl);
        return "redirect:/index";
    }

    /**
     * 相应图片，废弃
     * @param fileName
     * @param response
     */
    @GetMapping("/header/{fileName}")
    public void getHeader(@PathVariable("fileName") String fileName, HttpServletResponse response){
        // 服务器存放路径
        fileName = uploadPath + "/" + fileName;
        // 文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        //相应图片
        response.setContentType("image/" + suffix);
        try {
            InputStream is = new FileInputStream(fileName);
            OutputStream os = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int b;
            while ((b = is.read(bytes)) != -1){
                os.write(bytes, 0, b);
            }
        } catch (IOException e) {
            log.error("读取头像失败: " + e.getMessage());
        }
    }
    // 个人主页
    @RequestMapping(path = "/profile/{userId}", method = RequestMethod.GET)
    public String getProfilePage(@PathVariable("userId") int userId, Model model) {
        User user = userService.selectUserById(userId);
        if (user == null) {
            throw new RuntimeException("该用户不存在!");
        }

        // 用户
        model.addAttribute("user", user);
        // 点赞数量
        int likeCount = likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount", likeCount);

        // 关注数量
        long followeeCount = followService.findFolloweeCount(userId, ENTITY_TYPE_USER);
        model.addAttribute("followeeCount", followeeCount);
        // 粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER, userId);
        model.addAttribute("followerCount", followerCount);

        // 是否已关注
        boolean isFollow = false;
        if (hostHolder.getUser() != null) {
            isFollow = followService.hasFollowed(hostHolder.getUser().getId(), ENTITY_TYPE_USER, userId);
        }
        model.addAttribute("hasFollowed", isFollow);
        return "/site/profile";
    }

    /**
     * 修改密码
     */
    @GetMapping("/password")
    @ResponseBody
    public String updatePassword(String oldPassword, String newPassword){
        if (oldPassword.equals(newPassword)){
            return CommonUtils.getJSON(1, "新密码与旧密码一致");
        }
        User user = userService.selectUserById(hostHolder.getUser().getId());
        oldPassword = CommonUtils.MD5(oldPassword + user.getSalt());
        // 数据库密码与输入密码不一致
        if (!oldPassword.equals(user.getPassword())){
            return CommonUtils.getJSON(1, "旧密码输入错误!");
        }
        newPassword = CommonUtils.MD5(newPassword + user.getSalt());
        userService.updatePassword(user.getId(), newPassword);
        return CommonUtils.getJSON(0, "密码更新成功");
    }

}
